package com.atguigu.advanced.jvm;

import java.util.ArrayList;
import java.util.List;

/**
 * Package: com.atguigu.advanced.jvm
 *
 * @Description: 该类用于演示 Java 堆内存溢出（OutOfMemoryError）的情况。
 * 程序通过不断分配 byte 数组来模拟堆内存溢出，并在发生异常时打印内存信息。
 * @Author xiongkunYang
 * @Create 2025/5/16 17:54
 */


public class Test04 {

    /**
     * 程序入口方法，用于模拟 Java 堆内存溢出（OutOfMemoryError）。
     * 该方法首先打印初始堆内存状态，然后不断分配 1MB 大小的 byte 数组，
     * 直到触发堆内存溢出异常，并在捕获异常后打印调用次数和最终内存状态。
     *
     * @param args 命令行参数（未使用）
     */
    public static void main(String[] args) {
        // 打印堆内存状态
        MemoryInfo.printMemoryInfo();
        int count = 0;
        try {
            List<byte[]> list = new ArrayList<>();
            // 每次分配1MB大小的数组
            int size = 1024 * 1024;
            while (true) {
                list.add(new byte[size]);
                count++;
            }
        } catch (OutOfMemoryError e) {
            System.err.println("Heap OutOfMemoryError occurred: " + e.getMessage());
            System.out.println("方法调用了" + count + "次");
            // 打印堆内存状态
            MemoryInfo.printMemoryInfo();
            // 退出程序
            System.exit(1);
        }
    }

    /**
     * 打印当前 JVM 的堆内存使用情况，包括最大内存、已分配内存和空闲内存。
     */
    static class MemoryInfo {
        public static void printMemoryInfo() {
            Runtime runtime = Runtime.getRuntime();
            long maxMemory = runtime.maxMemory();
            long totalMemory = runtime.totalMemory();
            long freeMemory = runtime.freeMemory();
            System.out.println("Max memory: " + maxMemory / 1024 / 1024 + " MB");
            System.out.println("Total memory: " + totalMemory / 1024 / 1024 + " MB");
            System.out.println("Free memory: " + freeMemory / 1024 / 1024 + " MB");
        }
    }
}

